package com.topscore.utillibrary.widget.cyclebannerview;

import android.content.Context;
import android.content.res.TypedArray;
import android.os.Handler;
import android.support.v4.view.PagerAdapter;
import android.support.v4.view.ViewPager;
import android.util.AttributeSet;
import android.view.LayoutInflater;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageView;
import android.widget.RelativeLayout;

import com.topscore.utillibrary.R;

import java.util.ArrayList;
import java.util.List;

/**
 * Created by 71468 on 2018/3/9.
 * <p>
 * 广告图片自动轮播控件</br>
 * <p/>
 * <pre>
 *   集合ViewPager和指示器的一个轮播控件，主要用于一般常见的广告图片轮播，具有自动轮播和手动轮播功能
 *   使用：只需在xml文件中使用{@code <com.topscore.utillibrary.widget.cyclebannerview.ImageCycleView/>} ，
 *   然后在页面中调用  {@link #setBannerResourceInfo(List, BannerImageListener) }即可!
 *
 *   另外提供{@link #startImageCycle() } \ {@link #pushImageCycle() }两种方法，用于在Activity不可见之时节省资源；
 *   因为自动轮播需要进行控制，有利于内存管理
 * </pre>
 */

public class CirculatingBannerView<T extends BannerData> extends RelativeLayout {
    private Context mContext;

    /**
     * 设置滚动时间间隔
     */
    private long mTimeMillions = 2000;

    private CirculatingViewPager mViewPager = null;

    private List<T> mBannerDataList;

    private CycleImageAdapter mCycleImageAdapter;

    private ViewGroup mParent;

    /**
     * 图片滚动当前图片下标
     */
    private int mImageIndex = 1;


    private Runnable mImageTimerTask = () -> {
        if (mBannerDataList != null) {
            try {
                if (++mImageIndex == mBannerDataList.size() + 1) {
                    mImageIndex = 1;
                }
                mViewPager.setCurrentItem(mImageIndex);
            } catch (IllegalStateException e) {
                e.printStackTrace();
            }
        }
    };

    private Handler mHandler = new Handler();

    public CirculatingBannerView(Context context) {
        super(context);
    }

    public CirculatingBannerView(Context context, AttributeSet attrs) {
        this(context, attrs, 0);
    }

    public CirculatingBannerView(Context context, AttributeSet attrs, int defStyle) {
        super(context, attrs, defStyle);
        this.mContext = context;
        TypedArray typedArray = mContext.obtainStyledAttributes(attrs, R.styleable.CirculatingBannerView, defStyle, 0);
        mTimeMillions = typedArray.getInteger(R.styleable.CirculatingBannerView_timeMillions, 2000);
        LayoutInflater.from(mContext).inflate(R.layout.circulation_banner_container, this);
        mViewPager = (CirculatingViewPager) findViewById(R.id.viewpager);
        mViewPager.setOnPageChangeListener(new GuidePageChangerListener());
        mViewPager.setOnTouchListener((view, event) -> {
            switch (event.getAction()) {
                case MotionEvent.ACTION_UP:
                    startImageTimerTask();
                    break;
                default:
                    stopImageTimerTask();
                    break;
            }
            return false;
        });
    }

    /**
     * 装填轮播图数据
     *
     * @param bannerDataList
     * @param listener
     */
    public void setBannerResourceInfo(List<T> bannerDataList, BannerImageListener listener) {
        mBannerDataList = bannerDataList;
        mCycleImageAdapter = new CycleImageAdapter(mContext, bannerDataList, listener);
        mViewPager.setAdapter(mCycleImageAdapter);
    }

    public void setNestedpParent(ViewGroup parent) {
        this.mParent = parent;
        mViewPager.setNestedParent(parent);
    }

    /**
     * 开始滚动
     */
    private void startImageTimerTask() {
        stopImageTimerTask();
        mHandler.postDelayed(mImageTimerTask, mTimeMillions);
    }

    /**
     * 停止滚动
     */
    private void stopImageTimerTask() {
        mHandler.removeCallbacks(mImageTimerTask);
    }

    /**
     * 开始轮播(手动控制自动轮播与否，便于资源控制)
     */
    public void startImageCycle() {
        startImageTimerTask();
    }

    /**
     * 暂停轮播——用于节省资源
     */
    public void pushImageCycle() {
        stopImageTimerTask();
    }

    public interface BannerImageListener {
        void displayImage(BannerData data, ImageView imageView);

        void onImageClickListener(BannerData data, int position, View view);
    }

    private final class GuidePageChangerListener implements ViewPager.OnPageChangeListener {

        @Override
        public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {

        }

        @Override
        public void onPageSelected(int position) {

        }

        @Override
        public void onPageScrollStateChanged(int state) {

        }
    }

    private class CycleImageAdapter extends PagerAdapter {
        /**
         * 图片视图缓存列表
         */
        private ArrayList<ImageView> mImageViewCacheList;

        /**
         * 图片资源列表
         */
        private List<T> mAdList = new ArrayList<>();

        /**
         * 广告图片点击监听器
         */
        private BannerImageListener mImageCycleViewListener;

        private Context mContext;

        private CycleImageAdapter(Context context, List<T> bannerData, BannerImageListener bannerImageListener) {
            this.mContext = context;
            this.mImageViewCacheList = new ArrayList<>();
            this.mAdList = bannerData;
            mImageCycleViewListener = bannerImageListener;
        }

        @Override
        public boolean isViewFromObject(View view, Object object) {
            return view == object;
        }

        @Override
        public int getCount() {
            return mAdList.size();
        }

        @Override
        public Object instantiateItem(ViewGroup container, int position) {
            ImageView imageView = null;
            if (mImageViewCacheList.isEmpty()) {
                imageView = new ImageView(mContext);
                imageView.setLayoutParams(new ViewGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT));
                imageView.setScaleType(ImageView.ScaleType.CENTER_CROP);
            } else {
                imageView = mImageViewCacheList.remove(0);
            }
            T data = mAdList.get(position);
            mImageCycleViewListener.displayImage(data, imageView);
            imageView.setOnClickListener(view -> mImageCycleViewListener.onImageClickListener(data, position, view));
            container.addView(imageView);
            return imageView;
        }

        @Override
        public void destroyItem(ViewGroup container, int position, Object object) {
            ImageView view = (ImageView) object;
            container.removeView(view);
            mImageViewCacheList.add(view);
//            super.destroyItem(container, position, object);
        }
    }
}
